package com.cd.university.config.security.authentication.sms;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.SecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.DefaultSecurityFilterChain;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.rememberme.PersistentTokenBasedRememberMeServices;
import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository;
import org.springframework.stereotype.Component;

import java.util.UUID;

/**
 * 电话相关的Security配置
 * @author 陈栋
 * @create 2021/9/11 19:54
 */
@Component
public class SmsCodeAuthenticationSecurityConfig extends SecurityConfigurerAdapter<DefaultSecurityFilterChain, HttpSecurity> {
    /**
     * 注入UserDetailsService
     */
    @Autowired
    private UserDetailsService userDetailsService;

    /**
     * 注入成功处理器
     */
    @Autowired
    private AuthenticationSuccessHandler cdAuthenticationSuccessHandler;

    /**
     * 注入失败处理其
     */
    @Autowired
    private AuthenticationFailureHandler cdAuthenticationFailureHandler;

    /**
     * 用于存储用户的持久登录令牌的抽象。
     */
    @Autowired
    private PersistentTokenRepository persistentTokenRepository;

    @Override
    public void configure(HttpSecurity http) throws Exception {
        // 实例化一个smsCodeAuthenticationFilter
        SmsCodeAuthenticationFilter smsCodeAuthenticationFilter = new SmsCodeAuthenticationFilter();
        // 获得Spring security共享的AuthenticationManager类
        smsCodeAuthenticationFilter.setAuthenticationManager(http.getSharedObject(AuthenticationManager.class));
        // 放入处理成功和失败的处理器
        smsCodeAuthenticationFilter.setAuthenticationSuccessHandler(cdAuthenticationSuccessHandler);
        smsCodeAuthenticationFilter.setAuthenticationFailureHandler(cdAuthenticationFailureHandler);

        // 用于存储短信用户记住我的功能
        String key = UUID.randomUUID().toString();
        smsCodeAuthenticationFilter.setRememberMeServices(new PersistentTokenBasedRememberMeServices(
                key,
                userDetailsService,
                persistentTokenRepository
        ));

        // 创建并配置一个SmsCodeAuthenticationProvider
        SmsCodeAuthenticationProvider authenticationProvider = new SmsCodeAuthenticationProvider();
        authenticationProvider.setUserDetailsService(userDetailsService);

        http
                .authenticationProvider(authenticationProvider)
                // 把短信验证登录的过滤器加在UsernamePasswordAuthenticationFilter后面
                .addFilterAfter(smsCodeAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
    }
}
